package com.yu8home.mq.rabbit.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * https://blog.csdn.net/2301_79957017/article/details/135362569
 * <p>
 * 在RabbitMQ中，消息需要被序列化成字节流才能发送，接收方需要反序列化才能读取。
 * Spring Boot的spring-boot-starter-amqp默认使用Java序列化，但这种方式不推荐用于生产环境，
 * 因为它会导致跨语言或跨版本的不兼容问题。可以使用JSON序列化方式替代，通过自定义MessageConverter来实现。
 */
@Configuration
@Slf4j
public class RabbitConfig {

    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(messageConverter);
        return template;
    }


//    @Bean
//    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
//        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
//        container.setConnectionFactory(connectionFactory);
//        container.setQueueNames("yu8home.topic.cccc");
//        container.setAcknowledgeMode(AcknowledgeMode.AUTO);
//
//        container.setMessageListener((MessageListener) (message) -> {
//            log.info("接收消息：{}", new String(message.getBody()));
//
//            // throw new NullPointerException("消息消费失败"); 需要重新入队列
//            // throw new AmqpRejectAndDontRequeueException("消息消费失败"); 消息会被拒绝，且requeue=false
//            throw new ImmediateAcknowledgeAmqpException("消息消费失败：消费者会被确认");
//        });
//        return container;
//    }


    @Bean
    public SimpleMessageListenerContainer messageListenerContainer2(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("yu8home.topic.bbbb");// 监听队列
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);// 手动确认

        container.setMessageListener((ChannelAwareMessageListener) (message, channel) -> {
            log.info("接收消息：{}", new String(message.getBody()));

            if (message.getMessageProperties().getHeaders().get("error") == null) {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                log.info("消息确认");
            } else {
                // channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                log.info("消息拒绝");
            }
        });
        return container;
    }

}
